﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;
using System.Threading;
using Brain.IO;

namespace Brain.Editor
{
    public class DefaultEditorPluginManager : IEditorPluginManager
    {
        public List<LoadPlugin> PluginTypes { get; set; }

        public List<Assembly> PluginAssemblies { get; set;  }

        public DefaultEditorPluginManager()
        {
            PluginTypes = new List<LoadPlugin>();
            PluginAssemblies = new List<Assembly>();
        }

        public void HandleAssemblies(string rootFolder, FileInfo[] files)
        {
#if !WINDOWS_PHONE
            this.PluginTypes.Clear();
            this.PluginTypes = new List<LoadPlugin>();
            for (int i = 0; i < files.Length; i++)
            {
                FileInfo info = files[i];
                HandlePlugin(info);
            }
#endif
        }


        public void HandlePlugin(FileInfo pluginFile)
        {
            if (!pluginFile.Exists)
            {
                return;
            }

            if (pluginFile.Name.EndsWith(".bpl"))
            {
                // Brain 2 Plugin
                // We should consider reading the header of the file,
                // instead of just checking for the extension
                using (Stream str = pluginFile.OpenRead())
                {
                    BinaryFile file = BinaryFile.Separate(str, Environment.CurrentDirectory);

                    for (int i = 0; i < file.Files.Length; i++)
                    {
                        BinaryFileData data = file.Files[i];
                        HandlePlugin(new FileInfo(data.FileName));
                    }
                }

                return;
            }
#if WINDOWS_PHONE
            Assembly ass = Assembly.LoadFrom(pluginFile.FullName);
#else
            Assembly ass = Assembly.LoadFile(pluginFile.FullName);
#endif

            PluginAssemblies.Add(ass);

            if (ass != null)
            {
                Type[] types = ass.GetTypes();
                foreach (Type type in types)
                {
                    if (!type.IsInterface)
                    {
                        Type[] inter = type.GetInterfaces();
                        foreach (Type t in inter)
                        {
                            if (t == typeof(IEditorPlugin))
                            {
                                LoadPlugin load = new LoadPlugin();
                                load.PluginType = type;
                                load.Father = ass;
                                load.PluginAssemblyPath = pluginFile.FullName;
                                //load.PluginAssemblyPath = PathUtil.MakeRelative(rootFolder, pluginFile.FullName);
                                PluginTypes.Add(load);
                                break;
                            }
                        }
                    }
                }
            }
        }

        public IEditorPlugin Instantiate(LoadPlugin info)
        {
            IEditorPlugin Plugin = (IEditorPlugin) Activator.CreateInstance(info.PluginType);
            this.PluginTypes.Add(info);
            return Plugin;
        }
    }
}
